package grade.calculate.event;

import grade.calculate.pojo.Data;
import grade.calculate.pojo.StudentGrade;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

/**
 * 学业表现分输出
 * <p>实现了{@link Event}接口 读取方法执行完后 监听器会按照添加事件的顺序 运行事件的run方法</p>
 *
 * @author fromdrowning
 * @date 2024/2/20 19:35
 */
public class Write implements Event {

    /**
     * 输出Excel文件的表头
     */
    private final List<String> header = Arrays.asList(
            "编号",
            "姓名",
            "学业表现分（含体育）",
            "学业表现分（不含体育）"
    );

    /**
     * 文件输出路径
     */
    private final String outputFilePath;

    /**
     * 输出的表名 默认为学业表现分排名
     */
    private String outputSheetName;

    /**
     * 计算后的学生学业表现分集合
     */
    private List<StudentGrade> studentGradeList;

    /**
     * 带参构造方法
     *
     * @param outputFilePath 文件输出路径
     */
    public Write(String outputFilePath) {
        this.outputFilePath = outputFilePath;
    }

    /**
     * 学业表现分输出
     * <P>读取方法执行完后 监听器会按照添加事件的顺序 运行run方法</P>
     *
     * @param data {@link Data}中可以获取到启动时配置的参数和其它事件处理结果数据
     */
    @Override
    public void run(Data data) {
        init(data);

        try (FileOutputStream outputStream = new FileOutputStream(outputFilePath);
             Workbook workbook = new XSSFWorkbook()) {
            // 创建一张表 表名为启动时配置的表名
            Sheet sheet = workbook.createSheet(outputSheetName);

            writeHeader(sheet);
            writeGrade(sheet, studentGradeList);

            // 将数据输出为Excel文件
            workbook.write(outputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 初始化资源
     *
     * @param data {@link Data}中可以获取到启动时配置的参数和其它事件处理结果数据
     */
    private void init(Data data) {
        this.outputSheetName = data.getOutputSheetName();
        this.studentGradeList = data.getStudentGradeList();
    }

    /**
     * 写入表头
     *
     * @param sheet 准备输出的Excel文件的表
     */
    private void writeHeader(Sheet sheet) {
        Row row = sheet.createRow(0);
        for (int i = 0; i < header.size(); i++) {
            row.createCell(i).setCellValue(header.get(i));
        }
    }

    /**
     * 写入学业表现分
     *
     * @param sheet            准备输出的Excel文件的表
     * @param studentGradeList 学业表现分集合
     */
    private void writeGrade(Sheet sheet, List<StudentGrade> studentGradeList) {
        int i = 1;
        for (StudentGrade studentGrade : studentGradeList) {
            Row row = sheet.createRow(i);
            row.createCell(0).setCellValue(i);
            row.createCell(1).setCellValue(studentGrade.getName());
            row.createCell(2).setCellValue(studentGrade.getGradeIncludeSport());
            row.createCell(3).setCellValue(studentGrade.getGradeNoSport());
            i++;
        }
    }
}
